#include "reprst.h"
#include <string.h>
#include <stdio.h>

#define ONES5 (((uint64_t)1 << 5) - 1)

int set_bit(big_integer *x, int b) {
	if (b < 0 || b >= NUM_DIGITS * 32) {
		return 1;
	}
	x->digits[b >> 5] |= ((uint64_t)1 << (b & ONES5));
	return 0;
}

void clear_big_integer(big_integer *x) {
	memset(x->digits, 0, sizeof(x->digits));
}

void set_number(big_integer *x, uint32_t number) {
	clear_big_integer(x);
	x->digits[0] = number;
}

void print_big_integer(const big_integer *x) {
	fprint_big_integer(x, stdout);
}

void fprint_big_integer(const big_integer *x, FILE *fp) {
	int i;
	for (i = NUM_DIGITS - 1; i >= 0; --i) {
		if (x->digits[i] != 0) {
			fprintf(fp, "%" PRIx32, (uint32_t)(x->digits[i]));
			break;
		}
	}
	if (i < 0) {
		fprintf(fp, "0\n");
		return;
	}
	for (--i; i >= 0; --i) {
		fprintf(fp, "%08" PRIx32, (uint32_t)(x->digits[i]));
	}
	fprintf(fp, "\n");
}

void print_octet_string(const octet_string *s) {
	fprint_octet_string(s, stdout);
}

void fprint_octet_string(const octet_string *s, FILE *fp) {
	for (int i = 0; i < K_BYTES; ++i) {
		fprintf(fp, "%02" PRIx8, s->octets[i]);
	}
	fprintf(fp, "\n");
}

int get_bits(const big_integer *x) {
	for (int i = NUM_DIGITS - 1; i >= 0; --i) {
		for (int j = 31; j >= 0; --j) {
			if (x->digits[i] >> j & 1) {
				return ((i << 5) | j) + 1;
			}
		}
	}
	return 0;
}
